import Container from "@/components/container";
import s from './index.module.less'
import {useDispatch, useSelector} from "react-redux";
import {AppDispatch, RootState} from "@/redux/store.ts";
import {Button, Dropdown, Empty, Form, Modal, RadioGroup, Toast, Typography, UserGuide} from "@douyinfe/semi-ui";
import {IllustrationNoContent, IllustrationNoContentDark} from "@douyinfe/semi-illustrations";
import {
    IconBulb, IconDelete, IconEdit,
    IconEyeOpened,
    IconFolder,
    IconFolderOpen, IconMore,
    IconPaperclip,
    IconPlus, IconRefresh, IconRefresh2
} from "@douyinfe/semi-icons";
import {useCallback, useEffect, useRef, useState} from "react";
import {FormApi} from "@douyinfe/semi-ui/lib/es/form";
import {DsFile, DsServe} from "@/schemas/datasource.ts";
import {useFolderPicker} from "@/common/folder-io.ts";
import {StepItem} from "@douyinfe/semi-ui/lib/es/userGuide";
import {CreateDsFile, CreateDsServe, ListDatasource, LoadDatasource, SelectedDatasource} from "@/service/datasource.ts";
import {queryTen} from "@/common/default-some.ts";
import {RadioChangeEvent} from "@douyinfe/semi-ui/lib/es/radio";
import TableShow from "@/pages/datasource/table-show.tsx";


interface NullTipProps {
    onFileImportHandle?: () => void;
    onServeConnectHandle?: () => void;
}

const NullTip = (
    {onFileImportHandle, onServeConnectHandle}: NullTipProps
) => {

    const size = 150

    return <Container className={s.nullTipBox}>
        <Empty
            image={<IllustrationNoContent style={{width: size, height: size}}/>}
            darkModeImage={<IllustrationNoContentDark style={{width: size, height: size}}/>}
            title="还没有添加数据源..."
            description="立即添加一个数据源，开始数据分析！"
        >
            <div className={s.tools}>
                <Button type="tertiary" icon={<IconPaperclip/>} onClick={onServeConnectHandle}>
                    连接服务
                </Button>
                <Button icon={<IconFolder/>} onClick={onFileImportHandle}>
                    导入文件
                </Button>
            </div>
        </Empty>
    </Container>
}

interface ModalFormProps {
    visible: boolean;
    onClose: () => void;
    onRefresh: () => void;
}

const FileImportForm = (
    {visible, onClose}: ModalFormProps
) => {
    const api = useRef<FormApi<DsFile>>()

    const fileExtensionsMap: { [k: string]: string[] } = {
        excel: ['xlsx', 'xls'],
        sqlite: ['db'],
        json: ['json'],
        csv: ['csv'],
        all: ['xlsx', 'xls', 'db', 'json', 'csv']
    }

    const [selectedKind, setSelectedKind] = useState("all")

    const onKindSelect = (value: any) => {
        setSelectedKind(value);
        api?.current?.setValue('filePath', "")
    }

    const pickFile = useFolderPicker({
        title: '请选择要导入的数据文件',
        directory: false, // 明确指定选择文件夹
        multiple: false,
        filters: [
            {name: selectedKind, extensions: fileExtensionsMap[selectedKind]},
        ],
        onSuccess: (path) => {
            if (path) {
                api?.current?.setValue('filePath', path)
            }
        },
        onError: (error) => {
            console.log('路径选择错误:', error);
            Toast.error('路径选择错误！')
        }
    });

    const aiGuideSteps: StepItem[] = [
        {
            target: document.querySelector('#sql-input') || undefined,
            title: '首先：告诉 AI 要查的内容...',
            description: '在这里直接用人类的语言输入要查询的内容描述',
            position: 'top',
        },
        {
            target: document.querySelector('#sql-generate') || undefined,
            title: '然后：按下小灯泡～',
            description: '按下小灯泡，你的 AI 助理就会帮你生成出查询语句了！',
            position: 'top',
        },
        {
            target: document.querySelector('#sql-preview') || undefined,
            title: '最后：点击预览一下吧！',
            description: '如果查询出来的结果不太满意，可以尝试换一种表达和描述，多试几次哦～',
            position: 'top',
        },
    ]

    const [guideVisible, setGuideVisible] = useState(false)

    const dispatch = useDispatch<AppDispatch>()

    const submit = async () => {

        let formData = await api.current?.validate()

        if (formData) formData.dsId = ""

        dispatch(CreateDsFile(formData as DsFile))

        onClose()

    }

    return <Modal
        title="导入一个文件"
        visible={visible}
        onCancel={onClose}
        onOk={submit}
    >
        <Form getFormApi={formApi => api.current = formApi}>
            {/*name*/}
            <Form.Input field={'name'} label={'表名称'} showClear/>
            {/*kind*/}
            <Form.Select
                field={'kind'}
                label={'文件类型'}
                style={{width: '100%'}}
                onSelect={onKindSelect}
                optionList={[
                    {label: 'CSV文件 ( .csv ) ', value: 'csv'},
                    {label: 'Excel文件 ( .xls / .xlsx ) ', value: 'excel'},
                    {label: 'SQLite文件 ( .db ) ', value: 'sqlite'},
                    {label: 'Json文件 ( .json ) ', value: 'json'},
                ]}
            />
            {/*filePath*/}
            <Form.Input
                field={'filePath'}
                label={'文件路径'}
                suffix={<Button
                    size={"small"}
                    theme={"borderless"}
                    icon={<IconFolderOpen/>}
                    onClick={pickFile}
                    style={{marginRight: 2}}
                />}
            />

            {
                selectedKind === "sqlite" && <>
                    <Form.TextArea
                        field={'query'}
                        label={'查询语句(SQL)'}
                        id={'sql-input'}
                    />
                    <div className={s.aiTool}>
                        <Typography.Text
                            onClick={() => setGuideVisible(true)}
                            link underline
                            size={"small"}
                            style={{marginRight: 8}}
                        >试试AI生成?</Typography.Text>
                        <Button id={'sql-generate'} size={"small"} icon={<IconBulb/>}/>
                        <Button id={'sql-preview'} size={'small'} icon={<IconEyeOpened/>}/>
                    </div>
                </>
            }

        </Form>

        <UserGuide
            mode="popup"
            mask={true}
            visible={guideVisible}
            steps={aiGuideSteps}
            onFinish={() => setGuideVisible(false)}
            onSkip={() => setGuideVisible(false)}
        />

    </Modal>

}

const ServeConnectForm = ({visible, onClose}: ModalFormProps
) => {
    const api = useRef<FormApi<DsServe>>()

    const dispatch = useDispatch<AppDispatch>()

    const submit = async () => {
        let formData = await api.current?.validate()

        if (formData) formData.dsId = ""

        dispatch(CreateDsServe(formData as DsServe))

        onClose()
    }

    return <Modal
        title="连接到一个服务"
        visible={visible}
        onOk={submit}
        onCancel={onClose}
    >
        <Form getFormApi={formApi => api.current = formApi}>
            {/*name*/}
            <Form.Input field={'name'} label={'表名称'}/>
            {/*kind*/}

        </Form>

    </Modal>

}

const Datasource = () => {

    const {list, selected} = useSelector((state: RootState) => state.datasource);

    const [fileImportFormVisible, setFileImportFormVisible] = useState(false);

    const [serveConnectFormVisible, setServeConnectFormVisible] = useState(false);

    const dispatch = useDispatch<AppDispatch>();

    const fetchDatasource = useCallback(async () => {
        dispatch(ListDatasource(queryTen))
    }, [])

    useEffect(() => {
        fetchDatasource().then()
    }, [dispatch])

    const handleEdit = () => {
    }

    const handleDelete = () => {
    }

    const handleRefresh = () => {
        if (selected) dispatch(LoadDatasource(selected))
    }

    const changeSource = (event: RadioChangeEvent) => {
        const selectedDs = list.find(item => item.id === event.target.value)
        if (selectedDs) dispatch(SelectedDatasource(selectedDs))
    }

    const DsContent = () => {

        const [tabsWidth, setTabsWidth] = useState(100)

        const tableOptions = list.map((item) => ({
            label: item.name, value: item.id
        }))

        return <div
            className={s.content}
            ref={ref => setTabsWidth((ref?.clientWidth || 100) - 96)}
        >
            <div className={s.tableBox}>
                <TableShow/>
            </div>
            <RadioGroup
                className={s.tabsRadio}
                style={{width: tabsWidth}}
                options={tableOptions}
                type={'button'}
                onChange={changeSource}
                value={selected?.id}
            />
            <div className={s.tools}>
                <Dropdown
                    position={'topRight'}
                    menu={[
                        {
                            node: 'title',
                            name: '如何添加一个新的数据源？'
                        },
                        {
                            node: "item",
                            name: '导入文件',
                            icon: <IconFolder/>,
                            onClick: () => setFileImportFormVisible(true)
                        },
                        {
                            node: 'item',
                            name: '连接服务',
                            icon: <IconPaperclip/>,
                            onClick: () => setServeConnectFormVisible(true)
                        }
                    ]}
                >
                    <Button icon={<IconPlus/>}/>
                </Dropdown>
                <Dropdown
                    position={'topRight'}
                    menu={[
                        {
                            node: 'title',
                            name: '操作当前选中'
                        },
                        {
                            node: 'item',
                            name: '刷新/加载',
                            icon: <IconRefresh/>,
                            onClick: () => handleRefresh()
                        },
                        {
                            node: 'item',
                            name: '修改数据源',
                            icon: <IconEdit/>,
                            onClick: () => handleEdit()
                        },
                        {
                            node: 'item',
                            name: '删除数据源',
                            type: 'danger',
                            icon: <IconDelete/>,
                            onClick: () => handleDelete()
                        },
                        {node: 'divider'},
                        {
                            node: 'title',
                            name: '操作所有'
                        },
                        {
                            node: 'item',
                            name: '全部刷新',
                            icon: <IconRefresh2/>
                        }

                    ]}
                >
                    <Button type={"tertiary"} icon={<IconMore/>}/>
                </Dropdown>
            </div>
        </div>
    }

    return <Container className={s.container}>
        {
            list && list.length > 0 ?
                <DsContent/> :
                <NullTip
                    onFileImportHandle={() => setFileImportFormVisible(true)}
                    onServeConnectHandle={() => setServeConnectFormVisible(true)}
                />
        }
        <FileImportForm
            visible={fileImportFormVisible}
            onClose={() => setFileImportFormVisible(false)}
            onRefresh={fetchDatasource}
        />
        <ServeConnectForm
            visible={serveConnectFormVisible}
            onClose={() => setServeConnectFormVisible(false)}
            onRefresh={fetchDatasource}
        />
    </Container>;
}

export default Datasource;